/*
 * Created on 28/09/2005
 * Updated on 02/04/2010
 * @author renato
 */
package br.unb.graphics;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextPane;
import javax.swing.border.EmptyBorder;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;

import br.unb.core.status.StatusSocket;
import br.unb.utils.Console;
import br.unb.utils.Resource;

public class CommunicPanel extends JPanel {

    //TODO Constants, (move to another file)
    private static final String DESTINATION_IP = "destinationIP";
    private static final String ALL = "all";
    private static final String NEW_IP = "newIP";
    private static final String NEW_IP_LABEL = "newIPLabel";
    private static final String SEND = "send";
    private static final String TO_ALL = "toALL";
    private static final String TO = "to";
    private static final String TIMEOUT_ERROR = "timeoutError";
    private static final String NEW_IP_ACTION = "newIPAction";
    private static final String SEND_ACTION = "sendAction";
    JTextPane statusArea;
    JTextArea messageArea;
    JScrollPane statusBar, messageBar;
    JComboBox ipCombo;
    JLabel ipLabel;
    JPanel ipPanel, statusPanel, messagePanel;
    JButton messageButton;
    DefaultStyledDocument doc;
    StyleContext styles;
    private Action[] actions = {
        new NewIPAction(),
        new SendAction()
    };
    private boolean isShift;
    private InterfaceFactory ifactory;
    StatusSocket STATUS_SOCKET = StatusSocket.getInstance();

    /**
     * Build a new comunication panel
     * @param mController message controller
     */
    public CommunicPanel() {
        super(new BorderLayout());

        ifactory = new InterfaceFactory(Resource.CommunicPanel, actions);

        ipLabel = ifactory.createLabel(CommunicPanel.DESTINATION_IP);
        ipCombo = new JComboBox();
        ipCombo.addItem(ifactory.getResourceString(CommunicPanel.ALL));
        ipPanel = new JPanel(new FlowLayout());
        ipPanel.add(ipLabel);
        ipPanel.add(ipCombo);

        JButton newIpButton = ifactory.createButton(CommunicPanel.NEW_IP);
        ipPanel.add(newIpButton);
        styles = new StyleContext();
        createStyles();
        doc = new DefaultStyledDocument(styles);
        statusArea = new JTextPane(doc);
        statusArea.setBorder(new EmptyBorder(0, 5, 0, 5));
        statusArea.setEditable(false);

        statusBar = new JScrollPane(this.statusArea,
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        statusBar.setPreferredSize(new Dimension(200, 250));
        statusBar.getHorizontalScrollBar().setAutoscrolls(true);
        statusPanel = new JPanel(new FlowLayout());

        messageArea = new JTextArea(5, 45);
        messageArea.addKeyListener(new KeyListener() {

            public void keyPressed(KeyEvent ke) {
                if (ke.getKeyCode() == KeyEvent.VK_SHIFT) {
                    isShift = true;

                } else if (ke.getKeyCode() == KeyEvent.VK_ENTER) {
                    if (isShift) {
                        messageArea.setText(messageArea.getText() + "\n");
                    } else {
                        sendMessage();
                    }

                }
            }

            public void keyReleased(KeyEvent ke) {
                if (ke.getKeyCode() == KeyEvent.VK_SHIFT) {
                    isShift = false;
                }
            }

            public void keyTyped(KeyEvent ke) {
            }
        });

        messageArea.setBorder(new EmptyBorder(0, 5, 0, 5));
        messageArea.setLineWrap(true);
        messageBar = new JScrollPane(
                this.messageArea,
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        messageButton = ifactory.createButton(CommunicPanel.SEND);
        messagePanel = new JPanel(new BorderLayout());
        messagePanel.add(messageBar, BorderLayout.CENTER);
        messagePanel.add(messageButton, BorderLayout.EAST);
        add(statusBar, BorderLayout.NORTH);
        add(messagePanel, BorderLayout.CENTER);
        add(ipPanel, BorderLayout.SOUTH);
        setBorder(new EmptyBorder(5, 5, 5, 5));
    }

    void createStyles() {
        Color red, redDark, blue, blueDark;
        Font controlFont, messageFont;

        red = new Color(0xDC0C00);
        redDark = new Color(0x960000);
        blue = new Color(0x0000ff);
        blueDark = new Color(0x000096);
        controlFont = new Font("SansSerif", Font.BOLD, 12);
        messageFont = new Font("SansSerif", Font.ITALIC, 12);

        Style s1 = styles.addStyle("controlBlue", null);
        Style s2 = styles.addStyle("messageBlue", null);

        StyleConstants.setBold(s1, true);

        StyleConstants.setForeground(s1, blueDark);
        StyleConstants.setForeground(s2, blue);
        StyleConstants.setFontSize(s1, 12);
        StyleConstants.setFontSize(s2, 12);
    }

    private void sendMessage() {
        if (((String) ipCombo.getSelectedItem()).equals((String) ipCombo.getItemAt(0))) {
            //TODO Verify getResourceString() method
            //Console.println(ifactory.getResourceString(CommunicPanel.ALL));

            for (int i = 1; i < ipCombo.getItemCount(); i++) {
                STATUS_SOCKET.sendStatus(
                        messageArea.getText(),
                        (String) ipCombo.getItemAt(i));
            }
            addMessage(
                    ifactory.getResourceString(CommunicPanel.TO_ALL)
                    + messageArea.getText());
            messageArea.setText("");

        } else {
            STATUS_SOCKET.sendStatus(
                    messageArea.getText(),
                    (String) ipCombo.getSelectedItem());
            addMessage(
                    ifactory.getResourceString(CommunicPanel.TO)
                    + (String) ipCombo.getSelectedItem()
                    + ": " + messageArea.getText());
            messageArea.setText("");
        }
    }

    public void addMessage(String message) {
        String control = "";
        if (message.indexOf(":") >= 0) {
            control = message.substring(0, message.indexOf(":") + 1);
            message = message.substring(message.indexOf(":") + 1, message.length());
        }
        try {
            doc.insertString(doc.getLength(), control, styles.getStyle("controlBlue"));
            doc.insertString(doc.getLength(), message + "\n", styles.getStyle("messageBlue"));

            statusBar.getVerticalScrollBar().setValue(statusBar.getVerticalScrollBar().getMaximum());
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
    }

    /*********************************************************************/
    /*********************         ACTIONS           *********************/
    /*********************************************************************/
    class NewIPAction extends AbstractAction {

        NewIPAction() {
            super(NEW_IP_ACTION);
        }

        public void actionPerformed(ActionEvent e) {
            String ip = JOptionPane.showInputDialog(null, ifactory.getResourceString(NEW_IP_LABEL));
            ipCombo.addItem(ip);
            ipCombo.setSelectedItem(ip);
        }
    }

    class SendAction extends AbstractAction {

        SendAction() {
            super(SEND_ACTION);
        }

        public void actionPerformed(ActionEvent e) {
            sendMessage();
        }
    }
}
